package com.broada.apm.es.indices.service.impl;

import java.net.InetSocketAddress;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.indices.NodeIndicesStats;
import org.elasticsearch.monitor.fs.FsInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.broada.apm.es.bean.ClusterInfo;
import com.broada.apm.es.bean.NodeInfo;
import com.broada.apm.es.indices.service.IndexService;
import com.broada.apm.indicator.api.common.ApmDataIndicatorException;
import com.broada.apm.utils.EsClientUtil;

public class IndexServiceImpl implements IndexService {

	Logger LOG = LoggerFactory.getLogger(IndexServiceImpl.class);
	private Client client = EsClientUtil.getTransportClient();

	@Override
	public void buildIndex(String index) throws ApmDataIndicatorException {
		try {
			buildIndex(index, null, null);
			LOG.info("新建索引：" + index);
		} catch (Exception e) {
			throw new ApmDataIndicatorException(String.format("[%s]索引创建失败:%s", index, e));
		}
	}

	@Override
	public void buildIndex(String index, String alias, Settings indexSettings) throws ApmDataIndicatorException {
		try {
			CreateIndexRequestBuilder createIndexBuilder = client.admin().indices().prepareCreate(index);
			if (StringUtils.isNotEmpty(alias))
				createIndexBuilder.addAlias(new Alias(alias));
			if (indexSettings != null)
				createIndexBuilder.setSettings(indexSettings);
			createIndexBuilder.execute().actionGet();
		} catch (Exception e) {
			throw new ApmDataIndicatorException(String.format("[%s]索引创建失败:%s", index, e));
		}
	}

	@Override
	public void buildIndex(String index, String type, String alias, XContentBuilder mapping)
			throws ApmDataIndicatorException {
		buildIndex(index, type, alias, null, mapping);
	}

	@Override
	public void buildIndex(String index, String type, String alias, Settings indexSettings, XContentBuilder mapping)
			throws ApmDataIndicatorException {
		try {
			CreateIndexRequest indexRequest = new CreateIndexRequest(index);
			if (indexSettings != null)
				indexRequest.settings(indexSettings);
			indexRequest.alias(new Alias(alias));
			indexRequest.mapping(type, mapping);
			client.admin().indices().create(indexRequest).actionGet();
		} catch (Exception e) {
			throw new ApmDataIndicatorException(String.format("[%s]索引创建失败:%s", index, e));
		}
	}

	@Override
	public boolean existsIndex(String index) {
		return client.admin().indices().prepareExists(index).get().isExists();
	}

	@Override
	public boolean deleteIndex(String... indices) {
		if (!ArrayUtils.isEmpty(indices))
			return client.admin().indices().prepareDelete(indices).execute().actionGet().isAcknowledged();
		return true;
	}

	@Override
	public String[] searchIndex(String... indices) {
		if (!ArrayUtils.isEmpty(indices)) {
			GetIndexResponse response = client.admin().indices().prepareGetIndex().addIndices(indices).execute().actionGet();
			return response.getIndices();
		}
		return ArrayUtils.EMPTY_STRING_ARRAY;
	}

	@Override
	public ClusterInfo queryNodeStats() throws ApmDataIndicatorException {
		try {
			NodesStatsResponse response = client.admin().cluster().prepareNodesStats().clear().setFs(true).setIndices(true)
					.execute().actionGet();
			ClusterInfo cluster = new ClusterInfo(response.getClusterNameAsString());
			NodeInfo[] nodes = new NodeInfo[response.getNodes().length];
			for (int i = 0; i < response.getNodes().length; i++) {
				NodeStats nodeStats = response.getNodes()[i];
				// 获取所在磁盘信息
				FsInfo fs = nodeStats.getFs();
				long free = fs.getTotal().getAvailable().getBytes();
				long total = fs.getTotal().getTotal().getBytes();
				// 获取所属节点索引信息
				NodeIndicesStats indices = nodeStats.getIndices();
				long store = indices.getStore().getSize().getBytes();
				// 获取节点信息
				DiscoveryNode node = nodeStats.getNode();
				InetSocketTransportAddress transportAddress = (InetSocketTransportAddress) node.address();
				InetSocketAddress socketAddress = transportAddress.address();
				String address = socketAddress.getAddress().getHostAddress();
				String name = node.getName();
				nodes[i] = new NodeInfo(name, address, store, free, total);
			}
			cluster.setNodes(nodes);
			return cluster;
		} catch (Exception e) {
			throw new ApmDataIndicatorException("获取Elasticsearch集群节点失败", e);
		}
	}

}